import { computed, h, onMounted, onUnmounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';

// import { useAppConfig } from '@vben/hooks';
import { useAccessStore } from '@vben/stores';

import { Button, notification } from 'ant-design-vue';

import { BASE_ICON_URL } from '#/config'; // 引入全局配置

// const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);

const accessStore = useAccessStore();
const accessToken = computed(() => accessStore.accessToken);

export function useAudioNotification() {
  const router = useRouter();
  const audio = new Audio(
    'https://ai-app01.oss-cn-guangzhou.aliyuncs.com/mpweixin/hotel/xindan.mp3',
  ); // 新单提醒音频
  const modifyAudio = new Audio(
    'https://ai-app01.oss-cn-guangzhou.aliyuncs.com/mpweixin/hotel/xiugai.mp3',
  ); // 修改单提醒音频
  const renewalAudio = new Audio(
    'https://ai-app01.oss-cn-guangzhou.aliyuncs.com/mpweixin/hotel/xuzhu.mp3',
  ); // 续住单提醒音频
  const cancelAudio = new Audio(
    'https://ai-app01.oss-cn-guangzhou.aliyuncs.com/mpweixin/hotel/quxiao.mp3',
  ); // 续住单提醒音频
  // WebSocket 相关状态
  const ws = ref<null | WebSocket>(null); // WebSocket 实例
  const reconnectAttempts = ref(0); // 重连次数
  const MAX_RECONNECT_ATTEMPTS = 5; // 最大重连次数
  const RECONNECT_INTERVAL_BASE = 3000; // 基础重连间隔(ms)
  const HEARTBEAT_INTERVAL = 10_000; // 心跳间隔(ms)
  let heartbeatTimer: NodeJS.Timeout | null = null; // 心跳定时器
  let reconnectTimer: NodeJS.Timeout | null = null; // 重连定时器

  // 音频启用状态
  const storedAudioValue = localStorage.getItem('audioEnabled');
  const audioEnabled = ref<boolean>(
    storedAudioValue ? JSON.parse(storedAudioValue) : false,
  );
  // 通知启用状态
  const storedNotificationValue = localStorage.getItem('notificationEnabled');
  const notificationEnabled = ref<boolean>(
    storedNotificationValue ? JSON.parse(storedNotificationValue) : false,
  );
  // 通知权限状态
  const notificationPermission = ref<NotificationPermission>(
    'Notification' in window ? Notification.permission : 'default',
  );
  // 黑名单路由 以防万一出现在一下路由页面中，下面是需要过滤的页面
  const blacklistRoutes = new Set([
    '/auth/code-login',
    '/auth/forget-password',
    '/auth/login',
    '/auth/qrcode-login',
    '/auth/register',
  ]);

  // ================= 浏览器通知功能 =================
  // 检查通知支持
  const isNotificationSupported = () => {
    return 'Notification' in window;
  };

  // 显示浏览器通知右下角的通知
  const showBrowserNotification = (
    title: string,
    options?: NotificationOptions,
  ) => {
    if (
      !isNotificationSupported() ||
      notificationPermission.value !== 'granted'
    ) {
      return null;
    }
    const notification = new Notification(title, {
      icon: `${BASE_ICON_URL}logo-01.png`, // 通知图标
      badge: `${BASE_ICON_URL}logo-01.png`, // 标识
      ...options,
    });
    // 点击通知跳转
    notification.addEventListener('click', (event) => {
      event.preventDefault();
      if (options?.data?.url) {
        router.push(options.data.url);
      }
      window.focus();
      notification.close();
    });
    return notification;
  };

  // 请求通知权限
  const requestNotificationPermission = async () => {
    if (!isNotificationSupported()) {
      console.warn('浏览器不支持通知功能！');
      return false;
    }
    try {
      const permission = await Notification.requestPermission();
      notificationPermission.value = permission;
      if (permission === 'granted') {
        notificationEnabled.value = true;
        localStorage.setItem('notificationEnabled', 'true');
        // 发送测试通知
        showBrowserNotification('通知功能已启用', {
          body: '您已成功开启浏览器通知功能',
          data: { url: '/order/order-list' },
        });
        return true;
      } else {
        notificationEnabled.value = false;
        localStorage.setItem('notificationEnabled', 'false');
        return false;
      }
    } catch (error) {
      console.error('请求通知权限失败:', error);
      return false;
    }
  };

  // 处理被拒绝的权限
  const handleDeniedPermission = () => {
    if (blacklistRoutes.has(router.currentRoute.value.path)) return;
    const key = `notificationDenied-${Date.now()}`;
    notification.warning({
      style: {
        width: '400px',
      },
      message: '通知权限被拒绝',
      description: () =>
        h('div', [
          h('p', '您之前拒绝了浏览器通知权限，需要手动开启：'),
          h('ol', { style: 'margin-top: 4px;' }, [
            h('li', '1、点击浏览器地址栏左侧的锁形图标或信息图标'),
            h('li', '2、选择"网站设置"或"权限"'),
            h('li', '3、找到"通知"选项并更改为"允许"'),
            h('li', '4、刷新页面后生效'),
          ]),
        ]),
      btn: () =>
        h(
          Button,
          {
            type: 'primary',
            onClick: () => {
              notification.close(key);
            },
          },
          '知道了',
        ),
      key,
      duration: 30,
    });
  };

  // ================= 音频功能 =================
  const enableAudio = (key: string) => {
    audioEnabled.value = true;
    localStorage.setItem('audioEnabled', 'true');
    // 尝试播放静音音频以满足浏览器要求
    audio.volume = 0;
    audio
      .play()
      .then(() => {
        audio.pause();
        audio.currentTime = 0;
        notification.close(key);
        // 请求通知权限（用户交互后立即请求）
        if (
          isNotificationSupported() &&
          notificationPermission.value === 'default'
        ) {
          requestNotificationPermission();
        }
      })
      .catch((error) => {
        console.error('启用音频失败:', error);
      });
  };

  // 初始化提示开启音频
  const initAudio = () => {
    if (blacklistRoutes.has(router.currentRoute.value.path)) return;
    if (!audioEnabled.value) {
      const key = `initOpen`;
      notification.open({
        message: '通知设置',
        description: h('div', [
          h('p', '🔊 浏览器要求用户交互后才能播放音频。'),
          h(
            'p',
            { style: 'margin-top: 8px;' },
            '同时开启浏览器通知，即使页面最小化也能收到提醒',
          ),
        ]),
        duration: null,
        btn: () =>
          h(
            Button,
            {
              type: 'primary',
              onClick: () => enableAudio(key),
            },
            '开启消息播放',
          ),
        key,
      });
    }

    // 单独提示开启浏览器通知
    if (
      isNotificationSupported() &&
      notificationPermission.value === 'default'
    ) {
      const key = `notificationRequest-${Date.now()}`;
      notification.info({
        message: '开启浏览器通知',
        description: '即使离开页面或浏览器最小化，也能及时收到订单提醒',
        duration: null,
        btn: () =>
          h(
            Button,
            {
              type: 'primary',
              onClick: () => {
                requestNotificationPermission();
                notification.close(key);
              },
            },
            '开启浏览器通知',
          ),
        key,
      });
    }
  };

  const stopHeartbeat = () => {
    if (heartbeatTimer) {
      clearInterval(heartbeatTimer);
      heartbeatTimer = null;
    }
  };
  // 心跳机制
  const startHeartbeat = () => {
    stopHeartbeat();
    heartbeatTimer = setInterval(() => {
      if (ws.value && ws.value.readyState === WebSocket.OPEN) {
        ws.value.send(JSON.stringify({ type: 'heartbeat' }));
      }
    }, HEARTBEAT_INTERVAL);
  };
  // 处理订单通知
  const handleOrderNotification = (message: any) => {
    // 根据消息类型播放不同的音频  audio：新订单音频 modifyAudio：修改订单音频 RenewalAudio：续住订单音频
    let audioToPlay: HTMLAudioElement | null = null;
    const notificationTitle = '您有订单未处理哦！'; // 通知标题
    const notificationBody = '亲，您有订单未处理哦！请尽快来处理吧~'; // 通知内容

    switch (message.toString()) {
      case '1': {
        audioToPlay = audio;
        break;
      }
      case '2': {
        audioToPlay = modifyAudio;
        break;
      }
      case '3': {
        audioToPlay = renewalAudio;
        break;
      }
      case '4': {
        audioToPlay = cancelAudio;
        break;
      }
      default: {
        return;
      }
    }

    // 播放音频通知
    if (audioEnabled.value && audioToPlay) {
      try {
        audioToPlay.volume = 1;
        audioToPlay.play().catch((error) => {
          console.error('音频播放失败:', error);
          // 音频播放失败时提示用户
          notification.warning({
            message: '音频播放失败',
            description: '请确保浏览器允许自动播放音频',
            duration: 3,
          });
        });
      } catch (error) {
        console.error('音频播放错误:', error);
      }
    }

    // 显示页面通知
    const key = `orderNotification-${Date.now()}`;
    notification.open({
      message: notificationTitle,
      description: `🔊 ${notificationBody}`,
      duration: 10,
      btn: () =>
        h(
          Button,
          {
            type: 'primary',
            onClick: () => {
              router.push('/order/order-list');
              notification.close(key);
            },
          },
          '去处理',
        ),
      key,
    });

    // 显示浏览器通知
    if (notificationEnabled.value) {
      showBrowserNotification(notificationTitle, {
        body: `${notificationBody}`,
        data: { url: '/order/order-list' },
      });
    }

    // 触发订单页面更新事件
    const currentRoute = router.currentRoute.value.path;

    // 如果在订单列表页面
    if (currentRoute === '/order/order-list') {
      // 触发订单列表更新事件
      window.dispatchEvent(new CustomEvent('order-list-update'));
    }

    // 如果在首页
    if (currentRoute === '/home' || currentRoute === '/') {
      // 触发首页待处理订单更新事件
      window.dispatchEvent(new CustomEvent('pending-order-update'));
    }
  };

  // 发送消息到 WebSocket
  // const sendWebSocketMessage = (message: any) => {
  //   if (ws.value && ws.value.readyState === WebSocket.OPEN) {
  //     ws.value.send(JSON.stringify(message));
  //   } else {
  //     console.warn('WebSocket 未连接，消息发送失败');
  //   }
  // };

  // 初始化 WebSocket 连接
  const initWebSocket = () => {
    // 如果路由在黑名单中，或者没有token时需要阻止 WebSocket 连接
    if (
      blacklistRoutes.has(router.currentRoute.value.path) ||
      !accessToken.value
    ) {
      return;
    }
    // 关闭现有连接
    if (ws.value) {
      ws.value.close();
      ws.value = null;
    }
    // 清除重连定时器
    if (reconnectTimer) {
      clearTimeout(reconnectTimer);
      reconnectTimer = null;
    }
    // 创建新的 WebSocket 连接 ?token=${accessToken.value || ''}
    ws.value = new WebSocket(`wss://java.yijiahotel.com/ws`);

    // WebSocket 连接成功时初始化心跳检测
    ws.value.addEventListener('open', () => {
      console.warn('WebSocket 连接成功');
      reconnectAttempts.value = 0; // 重置重连次数
      startHeartbeat(); // 开始心跳检测
    });

    // WebSocket 收到消息时处理
    ws.value.addEventListener('message', (event) => {
      try {
        // 解析WebSocket返回的消息内容
        const message = event.data; // JSON.parse(event.data);
        // console.warn('收到 WebSocket 消息:', message);
        // 根据消息类型触发通知
        handleOrderNotification(message);
      } catch (error) {
        console.error('WebSocket 消息解析失败:', error);
      }
    });

    // WebSocket 关闭或错误时尝试重连
    ws.value.addEventListener('close', (event) => {
      console.warn(`WebSocket 连接关闭: ${event.code} ${event.reason}`);
      stopHeartbeat();
      // 非正常关闭时自动重连
      if (event.code !== 1000) {
        // 1000 表示正常关闭
        // eslint-disable-next-line no-use-before-define
        reconnect();
      }
    });

    ws.value.addEventListener('error', (error) => {
      console.error('WebSocket 错误:', error);
      stopHeartbeat();
      // eslint-disable-next-line no-use-before-define
      reconnect();
    });
  };

  // 重连机制
  const reconnect = () => {
    // 如果存在定时器或者已经达到最大重连次数，则不再尝试重连
    if (reconnectTimer || reconnectAttempts.value >= MAX_RECONNECT_ATTEMPTS) {
      return;
    }
    reconnectAttempts.value++; // 重连次数
    const delay = Math.min(
      RECONNECT_INTERVAL_BASE * 2 ** reconnectAttempts.value,
      30_000, // 最大重连间隔 30 秒
    );
    console.warn(
      `准备重新连接中(${reconnectAttempts.value}/${MAX_RECONNECT_ATTEMPTS})...`,
    );
    reconnectTimer = setTimeout(() => {
      console.warn(`重新连接中...`);
      initWebSocket();
      reconnectTimer = null;
    }, delay);
  };

  // 监听路由变化，防止路由进入黑名单路由时没有关闭通知的异常情况
  watch(
    () => router.currentRoute.value.path,
    (newPath) => {
      if (blacklistRoutes.has(newPath)) {
        // 在黑名单路由中，关闭 WebSocket
        if (ws.value) {
          ws.value.close();
          ws.value = null;
        }
        stopHeartbeat();
        if (reconnectTimer) {
          clearTimeout(reconnectTimer);
          reconnectTimer = null;
        }
      } else {
        // 不在黑名单中，确保连接已建立
        if (!ws.value || ws.value.readyState === WebSocket.CLOSED) {
          initWebSocket();
        }
      }
    },
    { immediate: true },
  );

  onMounted(() => {
    // 增加定时器防止页面初始化后导致一些以外情况
    const time = setTimeout(() => {
      initAudio();
      // 初始权限检查
      if (isNotificationSupported()) {
        notificationPermission.value = Notification.permission;
        // 处理之前被拒绝的情况
        if (notificationPermission.value === 'denied') {
          handleDeniedPermission();
        }
      }
      // 如果当前路由不在黑名单中，初始化 WebSocket
      // if (!blacklistRoutes.has(router.currentRoute.value.path)) {
      //   initWebSocket();
      // }
      clearTimeout(time);
    }, 1000);
  });

  // 组件卸载时清理（退出登录后清理）
  onUnmounted(() => {
    // 清理 WebSocket
    if (ws.value) {
      ws.value.close(1000, '组件卸载'); // 正常关闭
      ws.value = null;
    }
    // 清理定时器
    stopHeartbeat();
    if (reconnectTimer) {
      clearTimeout(reconnectTimer);
      reconnectTimer = null;
    }
  });

  return {
    audioEnabled,
    notificationEnabled,
    notificationPermission,
    enableAudio,
    requestNotificationPermission,
    showBrowserNotification,
  };
}
